package com.study.web.ztree;


import com.study.bean.Menu;
import com.study.bean.Menus;
import com.study.service.MenuService;
import com.study.web.SysBaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @ClassName MenuController
 * @Description 尚筹网|menu感觉不过，学习一下|sql文件位置 file/menu.sql
 * @Author 51
 * @Date 2020年4月23日16:23:10
 */
@SuppressWarnings({"unchecked", "rawtypes", "unused"})
@Slf4j
@Controller
@RequestMapping("/menu")
public class MenuController extends SysBaseController {
    @Resource
    JdbcTemplate jdbcTemplate;

    @Autowired
    MenuService menuService;

    /**
     * 菜单首页
     *
     * @return
     */
    @RequestMapping("/index")
    public String index(Model model) {
        return "menu/menu";
    }

    @GetMapping("/indexstream")
    public String indexjava8stream(Model model) {
        return "menu/menu2";
    }

    @GetMapping("/allnew")
    @ResponseBody
    public Object getMenu() {
        log.info("menu");
        // 只支持Integer.class String.class
        // 这种单数据类型的，自己定义的Bean不支|https://blog.csdn.net/J_mani/article/details/83896372?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
        // List<Menu> queryForList = jdbcTemplate.queryForList("select * from t_menu",
        // Menu.class);
        List<Menu> queryForList = jdbcTemplate.query("select id,pId ,name,url,icon from t_menu", new BeanPropertyRowMapper(Menu.class));
        System.out.println("AdminController.getALL()");
        log.info(queryForList.toString());
        return queryForList;
    }

    private <E> List<E> getAllmenu(Class<E> clazz) {
        return jdbcTemplate.query("select id,pId ,name,url,icon from t_menu", new BeanPropertyRowMapper(clazz.getClass()));
    }

    /**
     * getWholeTreeOld 和getWholeTreeNew|后者使用了 map这样来遍历查询，去map中的key，比前者方便
     *
     * @return
     */

    @GetMapping("/all_new")
    @ResponseBody
    public Object getWholeTreeNew() {

        // 1.查询全部的Menu对象
        List<Menus> menuList = jdbcTemplate.query("select id,pid ,name,url,icon from t_menu", new BeanPropertyRowMapper(Menus.class));

        // 2.声明一个变量用来存储找到的根节点
        Menus root = null;

        // 3.创建Map对象用来存储id和Menu对象的对应关系便于查找父节点
        Map<Integer, Menus> menuMap = new HashMap<>();

        // 4.遍历menuList填充menuMap
        for (Menus menu : menuList) {
            Integer id = menu.getId();
            menuMap.put(id, menu);
        }

        // 5.再次遍历menuList查找根节点、组装父子节点
        for (Menus menu : menuList) {

            // 6.获取当前menu对象的pid属性值
            Integer pid = menu.getPid();

            // 7.如果pid为null，判定为根节点
            if (pid == null) {
                root = menu;

                // 8.如果当前节点是根节点，那么肯定没有父节点，不必继续执行
                continue;
            }

            // 9.如果pid不为null，说明当前节点有父节点，那么可以根据pid到menuMap中查找对应的Menu对象
            Menus father = menuMap.get(pid);

            // 10.将当前节点存入父节点的children集合
            father.getChildren().add(menu);
        }
        return root;
    }

    @GetMapping("/all")
    @ResponseBody
    public Object getWholeTreeOld() {
        // 1.查询全部的Menu对象
        List<Menus> menuList = jdbcTemplate.query("select id,pid ,name,url,icon from t_menu", new BeanPropertyRowMapper(Menus.class));
        // 2.声明一个变量用来存储找到的根节点
        Menus root = null;
        // 3.遍历menuList
        for (Menus menu : menuList) {
            // 4.获取当前menu对象的pid属性值
            Integer pid = menu.getPid();
            // 5.检查pid是否为null
            if (pid == null) {
                // 6.把当前正在遍历的这个menu对象赋值给root
                root = menu;
                // 7.停止本次循环，继续执行下一次循环
                continue;
            }
            // 8.如果pid不为null，说明当前节点有父节点，找到父节点就可以进行组装，建立父子关系
            for (Menus maybeFather : menuList) {
                // 9.获取maybeFather的id属性
                Integer id = maybeFather.getId();
                // 10.将子节点的pid和疑似父节点的id进行比较
                if (Objects.equals(pid, id)) {
                    // 11.将子节点存入父节点的children集合
                    maybeFather.getChildren().add(menu);
                    // 12.找到即可停止运行循环
                    break;
                }

            }
        }
        log.info(root.toString());
        // 13.将组装的树形结构（也就是根节点对象）返回给浏览器
        return root;
    }

    /**
     * 使用java8 stream封装父子节点 关系
     */

    @GetMapping("/java8stream")
    @ResponseBody
    public Object java8stream() {
        log.info("menu with java8stream");
        return menuService.getAllwithJ8Stream();

    }

}
